<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import TodoHeader from './components/TodoHeader.vue'
import TodoItem from './components/TodoItem.vue'
import TodoList from './components/TodoList.vue'
import TodoFooter from './components/TodoFooter.vue'

const STORAGE_KEY = 'todolist-items'

const newTodoText = ref('')
const todos = ref([])
const activeFilter = ref('all') // all | active | completed

function loadFromStorage() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    todos.value = Array.isArray(JSON.parse(raw)) ? JSON.parse(raw) : []
  } catch (_) {
    todos.value = []
  }
}

function saveToStorage() {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(todos.value))
}

onMounted(loadFromStorage)
watch(todos, saveToStorage, { deep: true })

function addTodo() {
  const text = newTodoText.value.trim()
  if (!text) return
  todos.value.unshift({
    id: Date.now(),
    text,
    completed: false,
  })
  newTodoText.value = ''
}

function deleteTodo(id) {
  todos.value = todos.value.filter(t => t.id !== id)
}

function toggleTodo(id) {
  const target = todos.value.find(t => t.id === id)
  if (target) target.completed = !target.completed
}

function updateTodo(payload) {
  const target = todos.value.find(t => t.id === payload.id)
  if (target) target.text = payload.text
}

function clearCompleted() {
  todos.value = todos.value.filter(t => !t.completed)
}

const remainingCount = computed(() => todos.value.filter(t => !t.completed).length)
const completedCount = computed(() => todos.value.length - remainingCount.value)

const allChecked = computed({
  get() {
    return todos.value.length > 0 && remainingCount.value === 0
  },
  set(checked) {
    todos.value.forEach(t => (t.completed = checked))
  },
})

const filteredTodos = computed(() => {
  if (activeFilter.value === 'active') return todos.value.filter(t => !t.completed)
  if (activeFilter.value === 'completed') return todos.value.filter(t => t.completed)
  return todos.value
})

function setFilter(f) {
  activeFilter.value = f
}
</script>

<template>
  <section class="todo-app">
    <nav class="repo">
      <a class="repo-link" href="https://gitee.com/chrisKang111/hello-vue3.git" target="_blank" rel="noopener">代码仓库链接（在此替换为你的 gitee 地址）</a>
    </nav>

    <TodoHeader v-model:value="newTodoText" @add="addTodo" />

    <section v-if="todos.length" class="main">
      <label class="toggle-all">
        <input type="checkbox" v-model="allChecked" /> 全选
      </label>

      <TodoList
        :items="filteredTodos"
        @toggle="toggleTodo"
        @delete="deleteTodo"
        @update="updateTodo"
      />
    </section>

    <TodoFooter
      v-if="todos.length"
      :remaining="remainingCount"
      :completed="completedCount"
      :filter="activeFilter"
      @filter="setFilter"
      @clearCompleted="clearCompleted"
    />

    <p v-else class="empty">当前没有待办，添加一条试试～</p>

    <aside class="docs">
      <h3>子组件目录结构</h3>
      <pre>
src/components/
  ├─ TodoHeader.vue   输入与添加
  ├─ TodoItem.vue     单条项（勾选/编辑/删除）
  ├─ TodoList.vue     列表容器（渲染 TodoItem）
  └─ TodoFooter.vue   统计/筛选/清除
      </pre>
      <h3>组件属性与方法</h3>
      <ul>
        <li>TodoHeader: props value(String)；emits update:value, add</li>
        <li>TodoItem: props item(Object)；emits toggle(id), delete(id), update({id,text})</li>
        <li>TodoList: props items(Array)；向上传递子项事件</li>
        <li>TodoFooter: props remaining(Number), completed(Number), filter(String)；emits filter(type), clearCompleted()</li>
      </ul>
    </aside>
  </section>
</template>

<style scoped>
.todo-app {
  max-width: 720px;
  margin: 40px auto;
  padding: 20px 16px;
  border: 1px solid #eee;
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.06);
  background: #fff;
}
.title {
  margin: 0 0 12px;
  text-align: center;
}
.repo { display: flex; justify-content: center; margin-bottom: 8px; }
.repo-link { color: #42b883; }
.new {
  display: flex;
  gap: 8px;
}
.new input {
  flex: 1;
  height: 36px;
  padding: 0 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
}
.add {
  height: 36px;
  padding: 0 14px;
  background: #42b883;
  color: #fff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.toggle-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #666;
}
.docs { margin-top: 20px; color: #666; }
.docs pre { background: #f7f7f7; padding: 10px; border-radius: 8px; overflow: auto; }
.footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
}
.filters {
  display: flex;
  gap: 8px;
}
.filters button {
  padding: 4px 10px;
  border: 1px solid #eaeaea;
  background: #fafafa;
  border-radius: 6px;
  cursor: pointer;
}
.filters .active {
  color: #42b883;
  border-color: #42b883;
  background: #e8f8f1;
}
.clear:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.empty {
  margin: 60px 0;
  text-align: center;
  color: #888;
}
</style>
